# -*- coding:utf-8 -*-
# A.TNG

#import logging
import os
import wsgiref.handlers
import json
import logging

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import memcache
from bjlucentbus.model import *

#import datetime

#VALIDATE_IP_RANGE = ['127.0.0.1', '135.252', '135.244', '135.251', '192.11', '58.31.23']
VALIDATE_IP_RANGE = ['127.0.0.1']

def ip_out_of_range(h, ip):
    #h.response.out.write(u'''<h1>很抱歉，只能通过阿朗内部网络访问。</h1>
    #如果你是从阿朗内部网络访问的本站，却看到本条信息，请<a href="mailto: tang.jiyu@gmail.com">邮件我</a>，
    #告诉我你的IP <strong>('''+ip+u''')</strong>，我会将IP添加到允许访问的IP列表中来。
    #<h3>再次抱歉 :(</h3>''')
    h.response.out.write('<html><head><meta http-equiv="REFRESH" content="3; url=http://nwswww.cn.lucent.com/~gengjinh/bus/"></head><body>请访问ALU内网的班车地图： <a href="http://nwswww.cn.lucent.com/~gengjinh/bus/">http://nwswww.cn.lucent.com/~gengjinh/bus/</a></body></html>')

def ip_validation(fn):
    def v(*args):
        h = args[0]
        b_allowed = False
        
        try:
            remote_client = h.request.headers['X-Forwarded-For']
            logging.info('Get remote client IP from headers')
        except KeyError:
            remote_client = h.request.remote_addr
            logging.info('Get remote client IP from remote_addr')
        logging.info('remote addr: %s', remote_client)
        for ipaddr in VALIDATE_IP_RANGE:
            if 0 == remote_client.find(ipaddr):
                b_allowed = True
                break
            #logging.info(b_allowed)
        if b_allowed:
            return fn(*args)
        else:
            return ip_out_of_range(h, remote_client)
            #return fn(*args)
    return v

class MainPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        
        output = memcache.get('bjlucentbus')
        if output is not None:
            logging.info('bjlucentbus - MainPage - memcache')
            self.response.out.write(output)
            return
        
        path = os.path.join(os.path.dirname(__file__), 
                            'main.html')
        query_banche = Banche.all()
        query_banche.order('linenum')
        banches = query_banche.fetch(50)
        for banche in banches:
            banche.key = banche.key()
        
        jsons = []
        json_icons = []
        for banche in banches:
            jsons.append(self.genJsonBanche(banche.zhandianlist))
            json_icons.append(banche.icon)
        tpl_values = {
                      'banches':banches,
                      'jsons':json.write(jsons),
                      'json_icons':json.write(json_icons)
                      }
        output = template.render(path, tpl_values)
        memcache.add(key='bjlucentbus', value=output, time=3600) # timeout 1 hour
        self.response.out.write(output)
        
    def genJsonBanche(self, zhandianlist):
        json_zhandians = []
        for zhandian in zhandianlist:
            entity = db.get(zhandian)
            json_zhandian = {
                             'zhandianmingcheng':entity.zhandianmingcheng,
                             'lat':entity.lat,
                             'lng':entity.lng,
                             'zaoban': entity.zaoban,
                             'wanban': entity.wanban,
                             'zaobanshijian': entity.zaobanshijian,
                             }
            json_zhandians.append(json_zhandian)
        
        return json_zhandians
        
class LinePage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        path = os.path.join(os.path.dirname(__file__), 
                            'line.html')
        linenum = self.request.get('line', None)
        if linenum is None:
            self.response.out.write("ERROR")
            return
        
        banche = db.get(linenum)
        banche.key = banche.key()
        #q = db.GqlQuery('select * from Banche where linenum=:1', linenum)
        #banches = q.fetch(1)
        #banche = banches[0]
        zhandians =  []
        json_zhandians = []
        for zd in banche.zhandianlist:
            entity = db.get(zd)
            entity.key = entity.key()
            zhandians.append(entity)
            json_zhandian = {
                              'zhandianmingcheng':entity.zhandianmingcheng,
                              'lat':entity.lat,
                              'lng':entity.lng,
                              'zaoban': entity.zaoban,
                              'wanban': entity.wanban,
                              'zaobanshijian': entity.zaobanshijian,
                              }
            json_zhandians.append(json_zhandian)
        tpl_values = {
                      'banche':banche,
                      'zhandians':zhandians,
                      'json_zhandians':json.write(json_zhandians)
                      }
        self.response.out.write(template.render(path, tpl_values))
        
        
class SearchPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        path = os.path.join(os.path.dirname(__file__), 
                            'search.html')
        yigezhandian = self.request.get('key', None)
        banchekey = self.request.get('banchekey', None)
        if yigezhandian is None:
            self.response.out.write('ERROR')
            return
        
        zhandian = db.get(yigezhandian)
        zhandian.key = zhandian.key()
        #logging.info(zhandian.zhandianmingcheng)
        tpl_values ={
                     'zhandian':zhandian,
                     'banchekey':banchekey
                     }
        self.response.out.write(template.render(path, tpl_values))
        
class SamplePage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        path = os.path.join(os.path.dirname(__file__), 
                            'sample.html')
        self.response.out.write(template.render(path, {}))

class AjaxPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        # path = os.path.join(os.path.dirname(__file__), 'sample.html')
        key = self.request.get('key', 'none')
        lng = self.request.get('clickLng', 'none')
        lat = self.request.get('clickLat', 'none')
        if (key == 'none') or (lng == 'none') or (lat == 'none'):
            self.response.out.write('INVALID')
        else:
            zhandian = db.get(key)
            if zhandian is not None:
                zhandian.lng = lng
                zhandian.lat = lat
                zhandian.put()
                self.response.out.write('Save position successfully.')
            else:
                self.response.out.write('ERROR')

class AjaxLine(webapp.RequestHandler):
    '''列出对应key的班车的具体信息，包括站点信息
    '''
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        key = self.request.get('key', None)
        if key is None:
            self.response.out.write('[]')
        else:
            banche = db.get(key)
            if banche is not None:
                zhandians = []
                for zhandiankey in banche.zhandianlist:
                    entity = db.get(zhandiankey)
                    zhandian = {
                                'zhandianmingcheng':entity.zhandianmingcheng,
                                'lat':entity.lat,
                                'lng':entity.lng
                                }
                    zhandians.append(zhandian)
                self.response.out.write(json.write(zhandians))
            else:
                self.response.out.write('[]')
                
class EditLinePage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        path = os.path.join(os.path.dirname(__file__), 'editline.html')
        linekey = self.request.get('line', None)
        if linekey is None:
            self.response.out.write('ERROR')
            return
        banche = db.get(linekey)
        banche.key = banche.key()
        zhandians = []
        for idx, zd in enumerate(banche.zhandianlist):
            entity = db.get(zd)
            entity.key = entity.key()
            dict_entity = {
                          'busstop': entity.zhandianmingcheng,
                          'morningtime': entity.zaobanshijian,
                          'key': str(entity.key),
                          'note': entity.beizhu,
                          'morning': entity.zaoban and 'Yes' or 'No',
                          'night': entity.wanban and 'Yes' or 'No'
                           }
            try:
                if dict_entity.zaoban is True:
                    dict_entity['morning'] = 'Yes'           
                if dict_entity.wanban is True:
                    dict_entity['night'] = 'No'
            except:
                pass

            zhandians.append(dict_entity)

        tpl_value = {
                     'banche':banche,
                     'json':json.write(zhandians),
                     }
        self.response.out.write(template.render(path, tpl_value))
        
class DeleteZhandianPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        banche_key = self.request.get('banche_key', None)
        zhandian_key = self.request.get('zhandian_key', None)
        if banche_key is None or zhandian_key is None:
            self.response.out.write('ERROR')
            return
        else:
            banche = db.get(banche_key)
            zds = map(str, banche.zhandianlist)
            banche.zhandianlist.pop(zds.index(zhandian_key))
            banche.put()
            zd_entity = db.get(zhandian_key)
            zd_entity.delete()
#        self.response.out.write(banche_key+'---'+zhandian_key)
            self.response.out.write('OK')

class AddZhandianPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        banche_key = self.request.get('banche_key', None)
        zhandian_key = self.request.get('zhandian_key', None)
        if banche_key is None or zhandian_key is None:
            self.response.out.write('ERROR')
            return
        else:
            banche = db.get(banche_key)
            zds = map(str, banche.zhandianlist)
            new_zhandian = Zhandian(zhandianmingcheng=u'默认站点名称', 
                                    zaoban=False, wanban=False)
            new_key = new_zhandian.put()
            new_idx = zds.index(zhandian_key)
            banche.zhandianlist.insert(new_idx, new_key)
            banche.put()
            self.response.out.write(json.write({
                                                'busstop':u'默认站点名称',
                                                'key':str(new_key),
                                                'morning':'No',
                                                'night':'No',
                                                }))

class UpDownZhandianPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        banche_key = self.request.get('banche_key', None)
        zhandian_key = self.request.get('zhandian_key', None)
        action = self.request.get('action', None)
        if banche_key is None or zhandian_key is None or action is None:
            self.response.out.write('ERROR')
            return
        else:
            banche = db.get(banche_key)
            zds = map(str, banche.zhandianlist)
            idx = zds.index(zhandian_key)
            if action == 'up':
                if idx != 0:
                    # not the first one, then it can be moved up.
                    zd_key = banche.zhandianlist.pop(idx)
                    banche.zhandianlist.insert(idx-1, zd_key)
                    banche.put()
            elif action == 'down':
                if idx != (len(zds)-1):
                    # not the last one, then it can be moved down.
                    zd_key = banche.zhandianlist.pop(idx)
                    banche.zhandianlist.insert(idx+1, zd_key)
                    banche.put()
            else:
                # no match action
                pass
            self.response.out.write('OK')

class UpdateZhandianPage(webapp.RequestHandler):
#    def get(self):
#        self.response.headers['Content-Type'] = 'text/html'
#        self.response.out.write('ERROR')
    @ip_validation
    def post(self):
        self.response.headers['Content-Type']= 'text/html'
        banche_key = self.request.get('banche_key', None)
        if banche_key is not None:
            banche = db.get(banche_key)
            
#            update field
            zhandianmingcheng = self.request.get('zhandianmingcheng', None)
            if zhandianmingcheng is not None:
                banche.zhandianmingcheng = zhandianmingcheng
                banche.put()
                self.response.out.write(zhandianmingcheng)
                return
                
            zaobanshijian = self.request.get('zaobanshijian', None)
            if zaobanshijian is not None:
                banche.zaobanshijian = zaobanshijian
                banche.put()
                self.response.out.write(zaobanshijian)
                return
                
            beizhu = self.request.get('beizhu', None)
            if beizhu is not None:
                banche.beizhu = beizhu
                banche.put()
                self.response.out.write(beizhu)
                return
                
            zaoban = self.request.get('zaoban', None)
            if zaoban is not None:
                banche.zaoban = bool(zaoban == 'Yes')
                banche.put()
                self.response.out.write(banche.zaoban and 'Yes' or 'No')
                return
                
            wanban = self.request.get('wanban', None)
            if wanban is not None:
                banche.wanban = bool(wanban == 'Yes')
                banche.put()
                self.response.out.write(banche.wanban and 'Yes' or 'No')
                return
        else:
            self.response.out.write('ERROR')
            
class InitDataPage(webapp.RequestHandler):
    def get(self):
        #for i in xrange(833, 859):
        #    zd = Zhandian.get_by_id(i)
        #    self.response.out.write(zd.zhandianmingcheng)
        dbe_banche = Banche(linenum=u'10C线', chepaihao=u'京G', sijidianhua=u'魏师傅/13501079808', chezhangdianhua=u'鲍尚志', chexing=u'33+2', beizhu=u'None', linecolor='ffffff', icon='10c.png')
        dbe_zhandian = Zhandian(zhandianmingcheng=u'望京创业科技园', zaobanshijian='None', beizhu=u'', lat='MHGOQMIQPLLLL', lng='JIOMTRLPRUHLHL')
        dbe_banche.zhandianlist.append(dbe_zhandian.put())
        dbe_banche.put()
        self.response.out.write('ok')

class FirstPage(webapp.RequestHandler):
    @ip_validation
    def get(self):
        path = os.path.join(os.path.dirname(__file__),
            'first.html')
        query = Banche.all().order('linenum')
        banches = query.fetch(50)
        for banche in banches:
            banche.key = banche.key()
        tpl_value = {'banches':banches}
        output = template.render(path, tpl_value)
        self.response.out.write(output);
        
class ExportData(webapp.RequestHandler):
    def get(self):
        query = Banche.all()
        output = ''
        for b in query:
            # for banche information only
#            output += '%s, %s, %s, %s, %s<br>' % (
#                b.linenum,
#                b.chepaihao,
#                b.sijidianhua,
#                b.chezhangdianhua,
#                b.chexing
#            )

            # for banche and zhandian informaiton
            for z in b.zhandianlist:
                entity = db.get(z)
                output += '%s, %s, %s, %s, %s, %s, %s, %s<br>' % (
                    b.linenum,
                    entity.zhandianmingcheng,
                    entity.lng,
                    entity.lat,
                    entity.zaobanshijian,
                    entity.zaoban,
                    entity.wanban,
                    entity.beizhu,
                )
        self.response.out.write(output)

application = webapp.WSGIApplication([
                                      ('/bjlucentbus/main', MainPage),
                                      ('/bjlucentbus/', FirstPage),
                                      ('/bjlucentbus/search', SearchPage),
                                      ('/bjlucentbus/sample', SamplePage),
                                      ('/bjlucentbus/ajax', AjaxPage),
                                      ('/bjlucentbus/line', LinePage),
                                      ('/bjlucentbus/ajaxline', AjaxLine),
                                      ('/bjlucentbus/editline', EditLinePage),
                                      ('/bjlucentbus/deletezhandian', DeleteZhandianPage),
                                      ('/bjlucentbus/addzhandian', AddZhandianPage),
                                      ('/bjlucentbus/updownzhandian', UpDownZhandianPage),
                                      ('/bjlucentbus/updatezhandian', UpdateZhandianPage),
                                      #('/bjlucentbus/initdata', InitDataPage),
                                      #('/bjlucentbus/exportdata', ExportData),
                                      ], debug=True)

def main():
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()
